// kX Driver AC-3 front-end
// Copyright (c) Eugene Gavrilov, 2001-2005.
// All rights reserved

/*
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */


#ifndef _AC3_H_
#define _AC3_H_

#ifndef inline
 #define inline __inline
#endif

#ifndef DLIB
 #define DAC3	-12
 #define DLIB	2
 #define DWDM	3
#endif

#ifndef debug
 #if defined(KX_DEBUG_FUNC) && defined(KX_DEBUG)
  #define debug ((KX_DEBUG_FUNC)==0)?0:(KX_DEBUG_FUNC)
 #else
  #define debug (void)
 #endif
#endif

typedef unsigned __int64 uint_64;
typedef unsigned int   uint_32;
typedef unsigned short uint_16;
typedef unsigned char  uint_8;

typedef signed __int64 sint_64;
typedef signed int     sint_32;
typedef signed short   sint_16;
typedef signed char    sint_8;

/* Exponent strategy constants */
#define EXP_REUSE (0)
#define EXP_D15   (1)
#define EXP_D25   (2)
#define EXP_D45   (3)

#define UNPACK_FBW  1
#define UNPACK_CPL  2
#define UNPACK_LFE  4

/* Delta bit allocation constants */
#define DELTA_BIT_REUSE (0)
#define DELTA_BIT_NEW (1)
#define DELTA_BIT_NONE (2)
#define DELTA_BIT_RESERVED (3)

#define AC3_MAGIC_NUMBER 0xdeadbeef

/* samples work structure */
typedef float stream_samples_t[6][256];

/* Everything you wanted to know about band structure */
/*
 * The entire frequency domain is represented by 256 real
 * floating point fourier coefficients. Only the lower 253
 * coefficients are actually utilized however. We use arrays
 * of 256 to be efficient in some cases.
 *
 * The 5 full bandwidth channels (fbw) can have their higher
 * frequencies coupled together. These coupled channels then
 * share their high frequency components.
 *
 * This coupling band is broken up into 18 sub-bands starting
 * at mantissa number 37. Each sub-band is 12 bins wide.
 *
 * There are 50 bit allocation sub-bands which cover the entire
 * frequency range. The sub-bands are of non-uniform width, and
 * approximate a 1/6 octave scale.
 */

/* The following structures are filled in by their corresponding parse_*
 * functions. See http://www.atsc.org/Standards/A52/a_52.pdf for
 * full details on each field. Indented fields are used to denote
 * conditional fields.
 */

typedef struct syncinfo_s
{
	uint_32	magic;
	/* Sync word == 0x0B77 */
	/* uint_16   syncword; */
	/* crc for the first 5/8 of the sync block */
	/* uint_16   crc1; */
	/* Stream Sampling Rate (kHz) 0 = 48, 1 = 44.1, 2 = 32, 3 = reserved */
	uint_16		fscod;	
	/* Frame size code */
	uint_16		frmsizecod;

	/* Information not in the AC-3 bitstream, but derived */
	/* Frame size in 16 bit words */
	uint_16 frame_size;
	/* Bit rate in kilobits */
	uint_16 bit_rate;
	/* sampling rate in hertz */
	uint_32 sampling_rate;

} syncinfo_t;

typedef struct bsi_s
{
	uint_32	magic;
	/* Bit stream identification == 0x8 */
	uint_16 bsid;	
	/* Bit stream mode */
	uint_16 bsmod;
	/* Audio coding mode */
	uint_16 acmod;
	/* If we're using the centre channel then */
		/* centre mix level */
		uint_16 cmixlev;
	/* If we're using the surround channel then */
		/* surround mix level */
		uint_16 surmixlev;
	/* If we're in 2/0 mode then */
		/* Dolby surround mix level - NOT USED - */
		uint_16 dsurmod;
	/* Low frequency effects on */
	uint_16 lfeon;
	/* Dialogue Normalization level */
	uint_16 dialnorm;
	/* Compression exists */
	uint_16 compre;
		/* Compression level */
		uint_16 compr;
	/* Language code exists */
	uint_16 langcode;
		/* Language code */
		uint_16 langcod;
	/* Audio production info exists*/
	uint_16 audprodie;
		uint_16 mixlevel;
		uint_16 roomtyp;
	/* If we're in dual mono mode (acmod == 0) then extra stuff */
		uint_16 dialnorm2;
		uint_16 compr2e;
			uint_16 compr2;
		uint_16 langcod2e;
			uint_16 langcod2;
		uint_16 audprodi2e;
			uint_16 mixlevel2;
			uint_16 roomtyp2;
	/* Copyright bit */
	uint_16 copyrightb;
	/* Original bit */
	uint_16 origbs;
	/* Timecode 1 exists */
	uint_16 timecod1e;
		/* Timecode 1 */
		uint_16 timecod1;
	/* Timecode 2 exists */
	uint_16 timecod2e;
		/* Timecode 2 */
		uint_16 timecod2;
	/* Additional bit stream info exists */
	uint_16 addbsie;
		/* Additional bit stream length - 1 (in bytes) */
		uint_16 addbsil;
		/* Additional bit stream information (max 64 bytes) */
		uint_8	addbsi[64];

	/* Information not in the AC-3 bitstream, but derived */
	/* Number of channels (excluding LFE)
	 * Derived from acmod */
	uint_16 nfchans;
} bsi_t;


/* more pain */
typedef struct audblk_s
{
	uint_32	magic1;
	/* block switch bit indexed by channel num */
	uint_16 blksw[5];
	/* dither enable bit indexed by channel num */
	uint_16 dithflag[5];
	/* dynamic range gain exists */
	uint_16 dynrnge;
		/* dynamic range gain */
		uint_16 dynrng;
	/* if acmod==0 then */
	/* dynamic range 2 gain exists */
	uint_16 dynrng2e;
		/* dynamic range 2 gain */
		uint_16 dynrng2;
	/* coupling strategy exists */
	uint_16 cplstre;
		/* coupling in use */
		uint_16 cplinu;
			/* channel coupled */
			uint_16 chincpl[5];
			/* if acmod==2 then */
				/* Phase flags in use */
				uint_16 phsflginu;
			/* coupling begin frequency code */
			uint_16 cplbegf;
			/* coupling end frequency code */
			uint_16 cplendf;
			/* coupling band structure bits */
			uint_16 cplbndstrc[18];
			/* Do coupling co-ords exist for this channel? */
			uint_16 cplcoe[5];
			/* Master coupling co-ordinate */
			uint_16 mstrcplco[5];
			/* Per coupling band coupling co-ordinates */
			uint_16 cplcoexp[5][18];
			uint_16 cplcomant[5][18];
			/* Phase flags for dual mono */
			uint_16 phsflg[18];
	/* Is there a rematrixing strategy */
	uint_16 rematstr;
		/* Rematrixing bits */
		uint_16 rematflg[4];
	/* Coupling exponent strategy */
	uint_16 cplexpstr;
	/* Exponent strategy for full bandwidth channels */
	uint_16 chexpstr[5];
	/* Exponent strategy for lfe channel */
	uint_16 lfeexpstr;
	/* Channel bandwidth for independent channels */
	uint_16 chbwcod[5];
		/* The absolute coupling exponent */
		uint_16 cplabsexp;
		/* Coupling channel exponents (D15 mode gives 18 * 12 /3  encoded exponents */
		uint_16 cplexps[18 * 12 / 3];
	/* Sanity checking constant */
	uint_32	magic2;
	/* fbw channel exponents */
	uint_16 exps[5][252 / 3];
	/* channel gain range */
	uint_16 gainrng[5];
	/* low frequency exponents */
	uint_16 lfeexps[3];

	/* Bit allocation info */
	uint_16 baie;
		/* Slow decay code */
		uint_16 sdcycod;
		/* Fast decay code */
		uint_16 fdcycod;
		/* Slow gain code */
		uint_16 sgaincod;
		/* dB per bit code */
		uint_16 dbpbcod;
		/* masking floor code */
		uint_16 floorcod;

	/* SNR offset info */
	uint_16 snroffste;
		/* coarse SNR offset */
		uint_16 csnroffst;
		/* coupling fine SNR offset */
		uint_16 cplfsnroffst;
		/* coupling fast gain code */
		uint_16 cplfgaincod;
		/* fbw fine SNR offset */
		uint_16 fsnroffst[5];
		/* fbw fast gain code */
		uint_16 fgaincod[5];
		/* lfe fine SNR offset */
		uint_16 lfefsnroffst;
		/* lfe fast gain code */
		uint_16 lfefgaincod;
	
	/* Coupling leak info */
	uint_16 cplleake;
		/* coupling fast leak initialization */
		uint_16 cplfleak;
		/* coupling slow leak initialization */
		uint_16 cplsleak;
	
	/* delta bit allocation info */
	uint_16 deltbaie;
		/* coupling delta bit allocation exists */
		uint_16 cpldeltbae;
		/* fbw delta bit allocation exists */
		uint_16 deltbae[5];
		/* number of cpl delta bit segments */
		uint_16 cpldeltnseg;
			/* coupling delta bit allocation offset */
			uint_16 cpldeltoffst[8];
			/* coupling delta bit allocation length */
			uint_16 cpldeltlen[8];
			/* coupling delta bit allocation length */
			uint_16 cpldeltba[8];
		/* number of delta bit segments */
		uint_16 deltnseg[5];
			/* fbw delta bit allocation offset */
			uint_16 deltoffst[5][8];
			/* fbw delta bit allocation length */
			uint_16 deltlen[5][8];
			/* fbw delta bit allocation length */
			uint_16 deltba[5][8];

	/* skip length exists */
	uint_16 skiple;
		/* skip length */
		uint_16 skipl;

	//Removed Feb 2000 -ah
	/* channel mantissas */
	//uint_16 chmant[5][256];

	/* coupling mantissas */
	uint_16 cplmant[256];

	//Removed Feb 2000 -ah
	/* coupling mantissas */
	//uint_16 lfemant[7];


	/*  -- Information not in the bitstream, but derived thereof  -- */

	/* Number of coupling sub-bands */
	uint_16 ncplsubnd;

	/* Number of combined coupling sub-bands
	 * Derived from ncplsubnd and cplbndstrc */
	uint_16 ncplbnd;

	/* Number of exponent groups by channel
	 * Derived from strmant, endmant */
	uint_16 nchgrps[5];

	/* Number of coupling exponent groups
	 * Derived from cplbegf, cplendf, cplexpstr */
	uint_16 ncplgrps;
			
	/* End mantissa numbers of fbw channels */
	uint_16 endmant[5];

	/* Start and end mantissa numbers for the coupling channel */
	uint_16 cplstrtmant;
	uint_16 cplendmant;

	/* Decoded exponent info */
	uint_16 fbw_exp[5][256];
	uint_16 cpl_exp[256];
	uint_16 lfe_exp[7];

	/* Bit allocation pointer results */
	uint_16 fbw_bap[5][256];
	uint_16 cpl_bap[256];
	uint_16 lfe_bap[7];
	
	uint_32	magic3;
} audblk_t;

typedef struct ac3_state_s
{
 // fill-in function
 void (__stdcall *fill_buffer)(uint_8 **, uint_8 **,struct ac3_state_s *state,int size);

 // should be filled-in
 sint_16 *left;
 sint_16 *right;
 sint_16 *sleft;
 sint_16 *sright;
 sint_16 *center;
 sint_16 *subwoofer;

 // no user intersection....
 uint_32 sampling_rate;

 // in bit_allocate
 sint_16 sdecay;
 sint_16 fdecay;
 sint_16 sgain;
 sint_16 dbknee;
 sint_16 floor_;
 sint_16 psd[256];
 sint_16 bndpsd[256];
 sint_16 excite[256];
 sint_16 mask[256];

 // used in decode
 audblk_t audblk;
 bsi_t bsi;
 syncinfo_t syncinfo;
 uint_32 frame_count;

 uint_32 bits_left;
 uint_32 current_word;
 uint_16 lfsr_state;

 //the floating point samples for one audblk
 stream_samples_t samples;

 #define CHUNK_SIZE 2047
 int stop;

 #define BUFFER_SIZE 4096
 /*
 uint_8 *buffer_start;
 uint_8 *buffer_end;
 uint_8 *frame_start;
 */
 /* ------- */
 uint_8 buffer[BUFFER_SIZE];

 uint_8 *buffer_start, *buffer_end;
 uint_8 *chunk_start, *chunk_end;
 /* ------- */

 //These store the persistent state of the packed mantissas
 uint_16 m_1[3];
 uint_16 m_2[3];
 uint_16 m_4[2];
 uint_16 m_1_pointer;
 uint_16 m_2_pointer;
 uint_16 m_4_pointer;

 uint_16 state;

 // pointer to internal driver structure
 void *that;

 // debug function
 int (*debug_func)(int call_with,const char *__format, ... );
}ac3_state;


#ifdef WORDS_BIGENDIAN
	#define swab32(x) (x)
#else
	#define swab32(x)\
	((((uint_8*)&x)[0] << 24) | (((uint_8*)&x)[1] << 16) |  \
	 (((uint_8*)&x)[2] << 8)  | (((uint_8*)&x)[3]))
#endif

void bitstream_init(ac3_state *state);

uint_8 bitstream_get_byte(ac3_state *state);

uint_8 *bitstream_get_buffer_start(ac3_state *state);
void bitstream_buffer_frame(uint_32 frame_size,ac3_state *state);

uint_32 bitstream_get_bh(uint_32 num_bits,ac3_state *state);

void imdct(bsi_t *bsi,audblk_t *audblk, stream_samples_t samples);
void imdct_init(void);

void parse_syncinfo(syncinfo_t *syncinfo,int *error_flag,ac3_state *state);
void parse_audblk(bsi_t *bsi,audblk_t *audblk,ac3_state *state);
void parse_bsi(bsi_t *bsi,ac3_state *state);
void parse_auxdata(syncinfo_t *syncinfo,ac3_state *state);

void coeff_unpack(bsi_t *bsi, audblk_t *audblk,stream_samples_t samples,int *error_flag,ac3_state *state);

void exponent_unpack( bsi_t *bsi, audblk_t *audblk,int *error_flag,ac3_state *state);

int crc_validate(ac3_state *state);
void crc_init(ac3_state *state);
void crc_process_byte(uint_8 data,ac3_state *state);
void crc_process_frame(uint_8 *data,uint_32 num_bytes,ac3_state *state);

void sanity_check_init(syncinfo_t *syncinfo, bsi_t *bsi, audblk_t *audblk);
void sanity_check(syncinfo_t *syncinfo, bsi_t *bsi, audblk_t *audblk,int *error_flag,ac3_state *state);

void stats_print_syncinfo(syncinfo_t *syncinfo,ac3_state *state);
void stats_print_bsi(bsi_t *bsi,ac3_state *state);
void stats_print_audblk(bsi_t *bsi,audblk_t *audblk,ac3_state *state);
void stats_print_banner(syncinfo_t *syncinfo,bsi_t *bsi,ac3_state *state);

void rematrix(audblk_t *audblk, stream_samples_t samples);

void bit_allocate(uint_16 fscod, bsi_t *bsi, audblk_t *audblk,ac3_state *state);

extern const uint_16 dither_lut[256]; 

static inline uint_32 bitstream_get(uint_32 num_bits,ac3_state *state)
{
	uint_32 result;
	
	if(num_bits < state->bits_left)
	{
		result = (state->current_word << (32 - state->bits_left)) >> (32 - num_bits);
		state->bits_left -= num_bits;
		return result;
	}
	return bitstream_get_bh(num_bits,state);
}


static inline uint_16 dither_gen(ac3_state *state)
{
	sint_16 state_;

	state_ = (sint_16)(dither_lut[state->lfsr_state >> 8] ^ (state->lfsr_state << 8));
	
	state->lfsr_state = (uint_16) state_;

	return (sint_16)((state_ * (sint_32) (0.707106 * 256.0))>>8);
}

#ifdef __cplusplus
 extern "C" {
#endif

// ACTUAL EXPORTED FUNCTIONS

#ifdef AC3_EXPORTS
 #define AC3_CALLTYPE __declspec(dllexport)
#else
 #ifdef AC3_IMPORTS
  #define AC3_CALLTYPE __declspec(dllimport)
 #else
  #define AC3_CALLTYPE
 #endif
#endif

void AC3_CALLTYPE __stdcall ac3_init(ac3_state *state);
int AC3_CALLTYPE __stdcall ac3_decode_frame(ac3_state *state); 
 // 0 - success
 // !=0 - bad frame / error (output data is invalid and should be zeroed)

#ifdef __cplusplus
 };
#endif

#endif
